﻿using System;
using System.Security.Claims;
using System.Threading.Tasks;
using BlazorPro.BlazorSize;
using Google.Protobuf.Compiler;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using Microsoft.JSInterop;
using MudBlazor.Utilities;
using SageKing.UI.Blazor.SageKingAntDesign.Contracts;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Error = SageKing.UI.Blazor.SageKingAntDesign.Contracts.Error;

namespace SageKing.Blazor.OpenIdService.Components.Base;

public class AuthLayoutComponentTableBase : AuthLayoutComponentBase, ITableAutoSize, IAsyncDisposable
{
    public string LeftMenuAutoHideClass = "site-layout maleft201";

    public string ScrollX { get; set; } = "600";
    public string browserHeightPx { get; set; } = BrowserConsts.browserHeight.ToPx();
    public string browserHeightWithOutTopPx { get; set; } = BrowserConsts.browserHeight.ToPx();

    // windowsize
    public SKWindowSize? windowSize;

    //table height
    #region table auto size
    [Inject]
    public IResizeListener listener { get; set; }
    public Action StateHasChangedAction { get; set; }
    public ITableAutoSize MeTable { get { return this; } }
    public string ScrollY { get; set; } = BrowserConsts.ScrollY;
    public string ScrollY1080 { get; set; } = BrowserConsts.ScrollY1080;
    public double browserHeight { get; set; } = BrowserConsts.browserHeight;
    public double browserHeight1080 { get; set; } = BrowserConsts.browserHeight1080;
    public double ScrollYOffset { get; set; } = BrowserConsts.ScrollYOffset;
    public bool IsSmallMedia { get; set; } = false;
    // We can also capture the browser's width / height if needed. We hold the value here.
    public BrowserWindowSize browser { get; set; } = new BrowserWindowSize();
    public bool Islarge1080_800 { get; set; } = false;
    public string large1080_800 { get; set; } = BrowserAntDesignConsts.LargeHeight1080_800;
    #endregion


    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        StateHasChangedAction = () =>
        {
            updateHeightAction();
            StateHasChanged();
        };

        await MeTable.InitTableHeight(true);
        BrowserConsts.ScrollYTable = ScrollY;
    }
    void updateHeightAction()
    {
        ScrollY = $"{browserHeight - ScrollYOffset}px";
        BrowserConsts.ScrollYTable = ScrollY;
        browserHeightPx = browserHeight.ToPx();
        browserHeightWithOutTopPx = (browserHeight - TopOffset).ToPx();
        if (browser != null)
        {
            ScrollX = browser.Width.ToString();
        }
    }
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        try
        {
            if (firstRender)
            {
                await base.OnAfterRenderAsync(firstRender);

                // Subscribe to the OnResized event. This will do work when the browser is resized.
                listener.OnResized += MeTable.WindowResized; 

                windowSize = await GetSKWindowSize();
                if (windowSize != null)
                {
                    browserHeight = windowSize.pageHeight;

                    updateHeightAction();

                    BrowserConsts.WindowSize = windowSize;
                }

            }
            else
            {
                await GetSKWindowSize();
            }

            if (BrowserConsts.ScrollYTable != ScrollY)
            {
                updateHeightAction();
                StateHasChanged();
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }
    public async Task<SKWindowSize> GetSKWindowSize()
    {
        if (JsCommModule is not null)
        {
            if (IsDisposed)
            {
                return null;
            }

            // 异步等待获取锁。如果锁已被占用，此处不会阻塞线程，而是返回一个Task等待
            await _asyncLock.WaitAsync().ConfigureAwait(false);

            try
            {
                if (IsDisposed)
                {
                    return null;
                }

                windowSize = await JsCommModule.GetWindowSize();
                if (windowSize != null)
                {
                    BrowserConsts.WindowSize = windowSize;
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            finally
            {
                // 无论如何都要释放锁，确保锁最终会被释放，避免死锁
                _asyncLock.Release();
            }
        }
        return null;
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        try
        {

            if (JsCommModule is not null)
            {
                IsDisposed = true;
                await JsCommModule.DisposeAsync();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }

    #region tabs
    [Inject]
    ReuseTabsService ReuseTabsService { get; set; }

    [CascadingParameter]
    private Routes Routes { get; set; }

    public void Reload()
    {
        ReuseTabsService.ReloadPage();
    }

    public void CascadingChange(bool value)
    {
        ReuseTabsService.CloseAll();
        // Routes.SetCascadingRouteData(value);
    }

    #endregion
}
